package com.wyman.factory.support;

import com.wyman.BeanException;
import com.wyman.factory.ConfigurableListableBeanFactory;
import com.wyman.factory.config.BeanDefinition;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author 李伟民
 * @Description
 * DateTime 2024/11/25 01:44
 */


//AbstractAutowireCapableBeanFactory 负责创建bean
//BeanDefinitionRegistry 定义注册BeanDefinition的标准 具体注册BeanDefinition和获取BeanDefinition由该类实现

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry, ConfigurableListableBeanFactory {

    private final ConcurrentHashMap<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    //在之前的抽象类中有定义
    @Override
    public BeanDefinition getBeanDefinition(String beanName) throws BeanException {

        BeanDefinition beanDefinition =  beanDefinitionMap.get(beanName);
        if(beanDefinition == null){
            throw new BeanException("'没有'"+ beanName+"的BeanDefinition");
        }
        return beanDefinition;
    }

    @Override
    public void preInstantiateSingletons() throws BeanException {
        for(String beanName:beanDefinitionMap.keySet()){
            //12.11 默认都是调用无参构造方法初始化单例对象的
            getBean(beanName);
        }
    }

    @Override
    public boolean containsBeanDefinition(String beanName) {
        return beanDefinitionMap.containsKey(beanName);
    }

    @Override
    public <T> Map<String, T> getBeansOfType(Class<T> type) {
        Map<String,T> res = new HashMap<>();
        beanDefinitionMap.forEach((beanName,beanDefinition)->{
            Class beanClass = beanDefinition.getBeanClass();
            if(type.isAssignableFrom(beanClass)){
                res.put(beanName,getBean(beanName,type));
            }
        }
        );
        return res;
    }

    @Override
    public String[] getBeanDefinitionNames() {
        return beanDefinitionMap.keySet().toArray(new String[0]);
    }


    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName,beanDefinition);
    }


}
